home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Dots & Pixels
/
sources
/
C_randomizer.c
< prev
next >
Wrap
Text File
|
1995-09-29
|
5KB
|
181 lines
#include "C_randomizer.h"
static int seed_24_index = 24;
static int seed_55_index = 0;
static unsigned long randomizer_theseeds[ 55] =
{
1702803237, 3609857174, 1517566982, 1918061247, 1368775034,
3807181130, 66927828, 2508648394, 684483038, 1648047133,
2967841185, 252797108, 3864844816, 702424509, 683206901,
2289495513, 2594779536, 2502673239, 1159517122, 1677091079,
1260145853, 3188486680, 1282157716, 324433576, 1739387166,
3682410224, 4045723142, 2846836006, 3635585791, 11832984,
1985903735, 2287482506, 3383904320, 1140795862, 4220888830,
1317632102, 2580653160, 2614413823, 912417690, 3804890613,
1308492288, 652233149, 1450246829, 1664200832, 2764283166,
3236486674, 2592511403, 2283325954, 1972937535, 2802416540,
1405232398, 4064630287, 1580719194, 4053978138, 31904141,
};
unsigned long randomizer_step( void)
{
/*
// Note: copying the indices to temporary variables makes the
// code generated by THINK C shorter (and presumably faster)
*/
int seed_24_copy = seed_24_index;
int seed_55_copy = seed_55_index;
/*
// We don't care for overflow here;we want to do modular arithmetic!
*/
const unsigned long new_value =
randomizer_theseeds[ seed_24_copy] + randomizer_theseeds[ seed_55_copy];
randomizer_theseeds[ seed_55_copy] = new_value;
/*
// If seed_24 has to be reset we are sure that seed_55 has not to be reset,
// so we do not have to check for that in 1 in every 55 cases.
*/
if( seed_24_copy == 0)
{
seed_24_copy = 54;
seed_55_copy -= 1;
} else {
seed_24_copy -= 1;
if( seed_55_copy == 0)
{
seed_55_copy = 54;
} else {
seed_55_copy -= 1;
}
}
/*
// Finally copy our temporary copies back to the static ones
*/
seed_24_index = seed_24_copy;
seed_55_index = seed_55_copy;
return new_value;
}
void randomizer_fill( unsigned long *start, long numSteps)
{
/*
// Note: copying the indices to temporary variables makes the
// code generated by THINK C shorter (and presumably faster)
*/
int seed_24_copy = seed_24_index;
int seed_55_copy = seed_55_index;
int steps_to_go = numSteps;
/*
// We code for speed, using some ugly C hacks
*/
do
{
/*
// We don't care for overflow here;we want to do modular arithmetic!
*/
const unsigned long new_value = randomizer_theseeds[ seed_24_copy]
+ randomizer_theseeds[ seed_55_copy];
*start++ = randomizer_theseeds[ seed_55_copy] = new_value;
/*
// If seed_24 has to be reset we are sure that seed_55 has not to be
// reset, so we do not have to check for that in 1 in every 55 cases.
*/
if( seed_24_copy == 0)
{
seed_24_copy = 54;
seed_55_copy -= 1;
} else {
seed_24_copy -= 1;
if( seed_55_copy == 0)
{
seed_55_copy = 54;
} else {
seed_55_copy -= 1;
}
}
steps_to_go -= 1;
} while( steps_to_go != 0);
/*
// Finally copy our temporary copies back to the static ones
*/
seed_24_index = seed_24_copy;
seed_55_index = seed_55_copy;
}
double randomizer_a_double( void)
{
const int grain = 10000000;
int newvalue = randomizer_an_int( grain + 1);
/*
// newvalue is in the [0, grain] range now, so division by grain
// brings it in the [0, 1] range, multiplication by max_value
// brings it in the requested range. To ensure that the result
// won't get bigger than 'max_value' or less than zero we handle
// the two extreme cases separately. Rounding errors for the other
// cases will not lead to these errors (unless grain is very big,
// of course). We also don't check whether 'max_value > 0.0'
// and/or 'grain > 1', but what the heck...
*/
double result;
if( newvalue == 0)
{
result = 0.0;
} else if( newvalue == grain) {
result = 1.0;
} else {
result = (double)newvalue / grain;
}
return result;
}
void randomizer_reseed( unsigned long seed)
{
unsigned long newseeds[ 55];
int i;
for( i = 0; i < 55; i++)
{
newseeds[ i] += randomizer_step() + seed;
}
/*
// Note: if seed is even we can be sure that not all newseeds are even
// since step() cannot return 55 even numbers in a row.
// If seed is odd, however, we have to make sure
// (step() can return 55 odd numbers in a row).
*/
if( seed & 1)
{
int all_seeds_are_even = 1;
for( i = 0; i < 55; i++)
{
if( newseeds[ i] & 1)
{
all_seeds_are_even = 0;
break;
}
}
if( all_seeds_are_even)
{
/*
// calling randomizer_an_int does not return a uniformly
// distributed random integer here, but what the heck...
*/
const int one_to_make_odd = randomizer_an_int( 55);
/*
// we know that the seed is even, so addition of 1 makes it odd
*/
newseeds[ one_to_make_odd] += 1;
}
}
for( i = 0; i < 55; i++)
{
randomizer_theseeds[ i] = newseeds[ i];
}
}